//
//  JRTXDiagramView.m
//  
//
//  Created by JIRENTIANXIANG on 6/21/15.
//
//

#import "JRTXDiagramView.h"
#import "JRTXDiagramPoint.h"

@implementation JRTXDiagramViewLineStyle

+(JRTXDiagramViewLineStyle*)lineStyleWithColor:(UIColor *)color lineWidth:(CGFloat)lineWidth segmentLength:(CGFloat)segmentLength gapLength:(CGFloat)gapLength
{
    JRTXDiagramViewLineStyle* lineStyle=[[JRTXDiagramViewLineStyle alloc] init];
    lineStyle.color=color;
    lineStyle.lineWidth=lineWidth;
    lineStyle.segmentLength=segmentLength;
    lineStyle.gapLength=gapLength;
    return lineStyle;
}

@end

@interface JRTXDiagramView ()

@property (strong,nonatomic) NSArray* diagramCoordsArray;

@end

@implementation JRTXDiagramView

-(instancetype)initWithFrame:(CGRect)frame configuration:(JRTXDiagramViewConfiguration *)config
{
    if (self=[super initWithFrame:frame]) {
        self.configuration=config;
        CGFloat leftPadding=self.configuration.leftPadding;
        CGFloat rightPadding=self.configuration.rightPaddig;
        CGFloat topPadding=self.configuration.topPadding;
        CGFloat bottomPadding=self.configuration.bottomPadding;
        CGPoint origin=self.bounds.origin;
        CGSize size=self.bounds.size;
        self.graphArea=CGRectMake(origin.x+leftPadding, origin.y+topPadding, size.width-leftPadding-rightPadding, size.height-topPadding-bottomPadding);
        self.mapper=[JRTXDiagramDataDisplayMapper mapperForDiagramView:self];
    }
    return self;
}

-(void)setDiagramData:(NSArray *)diagramData
{
    _diagramData=diagramData;
    [self.mapper update];
    self.diagramCoordsArray=self.mapper.points;
}

-(void)layoutSubviews
{
    for (UIView* view in self.subviews) {
        [view removeFromSuperview];
    }
    if (self.dataSource&&self.diagramCoordsArray&& self.diagramCoordsArray.count>2) {
        if ([self.dataSource respondsToSelector:@selector(numberOfXIndicesInDiagramView:)]&&[self.dataSource respondsToSelector:@selector(diagramView:viewForXIndex:)]&&[self.dataSource respondsToSelector:@selector(diagramView:valueForXIndex:)]) {
            NSInteger xIndexCount=[self.dataSource numberOfXIndicesInDiagramView:self];
            for (int i=0; i<xIndexCount; i++) {
                NSNumber* value=[self.dataSource diagramView:self valueForXIndex:i];
                CGFloat xCoord=[self.mapper xCoordFromValue:value];
                if (!isnan(xCoord)) {
                    UIView* view=[self.dataSource diagramView:self viewForXIndex:i];
                    CGPoint origin=self.graphArea.origin;
                    CGSize size=self.graphArea.size;
                    CGFloat yCoord=origin.y+size.height+view.frame.size.height/2;
                    if (!isnan(yCoord)) {
                        view.center=CGPointMake(xCoord, yCoord);
                        [self addSubview:view];
                    }
                }
            }
        }
        if ([self.dataSource respondsToSelector:@selector(numberOfYIndicesInDiagramView:)]&&[self.dataSource respondsToSelector:@selector(diagramView:viewForYIndex:)]&&[self.dataSource respondsToSelector:@selector(diagramView:valueForYIndex:)]) {
            NSInteger yIndexCount=[self.dataSource numberOfYIndicesInDiagramView:self];
            for (int i=0; i<yIndexCount; i++) {
                NSNumber* value=[self.dataSource diagramView:self valueForYIndex:i];
                CGFloat yCoord=[self.mapper yCoordFromValue:value];
                UIView* view=[self.dataSource diagramView:self viewForYIndex:i];
                CGFloat xCoord=self.graphArea.origin.x-view.frame.size.width/2;
                if (!isnan(xCoord)&&!isnan(yCoord)) {
                    view.center=CGPointMake(self.graphArea.origin.x-view.frame.size.width/2,yCoord);
                }
                [self addSubview:view];
            }
        }
    }
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    if (self.diagramCoordsArray&& self.diagramCoordsArray.count>2) {
        CGPoint origin=self.graphArea.origin;
        CGSize size=self.graphArea.size;
        
        CGContextRef context=UIGraphicsGetCurrentContext();
        CGContextSetLineJoin(context, kCGLineJoinRound);
        CGContextSetLineWidth(context, self.configuration.lineWidth);
        CGContextSetStrokeColorWithColor(context, self.configuration.lineColor.CGColor);
        JRTXDiagramPoint* firstPoint=self.diagramCoordsArray.firstObject;
        CGContextMoveToPoint(context, firstPoint.point.x, firstPoint.point.y);
        for (JRTXDiagramPoint* coords in self.diagramCoordsArray) {
            CGPoint point=coords.point;
            CGContextAddLineToPoint(context, point.x, point.y);
        }
        CGContextStrokePath(context);
        
        CGContextMoveToPoint(context, firstPoint.point.x, firstPoint.point.y);
        for (JRTXDiagramPoint* coords in self.diagramCoordsArray) {
            CGPoint point=coords.point;
            CGContextAddLineToPoint(context, point.x, point.y);
        }
        CGContextAddLineToPoint(context, origin.x+size.width, origin.y+size.height);
        CGContextAddLineToPoint(context, origin.x, origin.y+size.height);
        CGContextClosePath(context);
        CGContextSetFillColorWithColor(context, self.configuration.shadowColor.CGColor);
        CGContextFillPath(context);
        if ([self.dataSource respondsToSelector:@selector(numberOfYIndicesInDiagramView:)]&&[self.dataSource respondsToSelector:@selector(diagramView:valueForYIndex:)]&&[self.dataSource respondsToSelector:@selector(diagramView:lineStyleForYIndex:)]) {
            NSInteger count=[self.dataSource numberOfYIndicesInDiagramView:self];
            CGFloat left=self.graphArea.origin.x;
            CGFloat right=self.graphArea.origin.x+self.graphArea.size.width;
            for (int i=0; i<count-1; i++) {
                NSNumber* value=[self.dataSource diagramView:self valueForYIndex:i];
                CGFloat yCoord=[self.mapper yCoordFromValue:value];
                JRTXDiagramViewLineStyle* lineStyle=[self.dataSource diagramView:self lineStyleForYIndex:i];
                CGFloat leftEnd=left;
                while ((leftEnd+=lineStyle.segmentLength+lineStyle.gapLength)<right) {
                    if (!isnan(leftEnd)&&!isnan(yCoord)) {
                        CGContextMoveToPoint(context, leftEnd, yCoord);
                    }
                    
                    CGContextAddLineToPoint(context, leftEnd+lineStyle.segmentLength, yCoord);
                }
                CGContextSetStrokeColorWithColor(context, lineStyle.color.CGColor);
                CGContextSetLineWidth(context, lineStyle.lineWidth);
                CGContextStrokePath(context);
            }
        }
    }
}

-(void)updateDisplay
{
    [self setNeedsLayout];
    [self setNeedsDisplay];
}

@end
